#include <types.h>

#include <api/libc/list.h>
#include <api/libc/alloc.h>

#include <api/libmp/pe.h>
#include "plugin.h"
#include "music_engine.h"

//#ifdef SUPPORT_MPEG4_TEST
//#include "../../libmp4dec/decoder/Common/com_def.h"
//#endif

#ifdef DUAL_ENABLE
#include <modules.h>

enum MUSIC_ENGINE_FUNC{
    FUNC_MUSIC_ENGINE_INIT = 0,   
    FUNC_MUSIC_ENGINE_RELEASE,
    FUNC_MUSIC_ENGINE_PLAY,
    FUNC_MUSIC_ENGINE_SEEK,
    FUNC_MUSIC_ENGINE_STOP,
    FUNC_MUSIC_ENGINE_PAUSE,
    FUNC_MUSIC_ENGINE_GET_TIME,
    FUNC_MUSIC_ENGINE_SET_EQ,
    FUNC_MUSIC_ENGINE_GET_SONG_INFO,
    FUNC_MUSIC_ENGINE_GET_DECODER_INFO,
    FUNC_MUSIC_ENGINE_SET_DISABLE_SEEK,
    FUNC_MUSIC_ENGINE_SET_OTHER_INFO,
};

#ifndef _LIB_PE_MUSIC_ENGINE_REMOTE

int music_engine_init(struct pe_music_cfg *pe_music_cfg);
void music_engine_release();
int music_engine_play(char *filename);
void music_engine_seek(int time);
void music_engine_stop(void);
void music_engine_pause(void);
int music_engine_get_time(void);
void music_engine_set_eq(int on, float preamp, float *bands);
int music_engine_get_song_info(char * filename, MusicInfo *music_info);
int music_engine_get_decoder_info(char * filename, DecoderInfo *decoder_info);
void music_engine_set_disableSeek(UINT8 disable);
int music_engine_set_other_info(UINT32 cmd, UINT32 param1);
UINT32 music_engine_entry[] = 
{
    (UINT32)music_engine_init,
    (UINT32)music_engine_release,
    (UINT32)music_engine_play,
    (UINT32)music_engine_seek,
    (UINT32)music_engine_stop,
    (UINT32)music_engine_pause,
    (UINT32)music_engine_get_time,
    (UINT32)music_engine_set_eq,
    (UINT32)music_engine_get_song_info,
    (UINT32)music_engine_get_decoder_info,
    (UINT32)music_engine_set_disableSeek,
    (UINT32)music_engine_set_other_info,
};

void lib_pe_music_engine_callee(UINT8 *msg)
{
    OS_hld_callee(music_engine_entry, msg);
}

#endif

#ifdef _LIB_PE_MUSIC_ENGINE_REMOTE
static UINT32 desc_me_init[] = 
{ //desc of pointer para
  1, DESC_STATIC_STRU(0, sizeof(struct pe_music_cfg)), 
  1, DESC_P_PARA(0, 0, 0),
  //desc of pointer ret
  0,                          
  0,
};

static UINT32 desc_me_set_eq[] = 
{ //desc of pointer para
  1, DESC_OUTPUT_STRU(0, sizeof(float)),  
  1, DESC_P_PARA(0, 2, 0),
  //desc of pointer ret
  0,                          
  0,
};

static UINT32 desc_me_get_song_info[] = 
{ //desc of pointer para
  1, DESC_OUTPUT_STRU(0, sizeof(MusicInfo)), 
  1, DESC_P_PARA(0, 1, 0),
  //desc of pointer ret
  0,                          
  0,
};

static UINT32 desc_me_get_decoder_info[] = 
{ //desc of pointer para
  1, DESC_OUTPUT_STRU(0, sizeof(DecoderInfo)), 
  1, DESC_P_PARA(0, 1, 0),
  //desc of pointer ret
  0,                          
  0,
};

static UINT32 desc_me_set_other_info[] = 
{ //desc of pointer para
  1, DESC_STATIC_STRU(0, sizeof(MusicInfo)),  
  1, DESC_P_PARA(0, 1, 0),
  //desc of pointer ret
  0,                          
  0,
};

#ifdef _INVW_JUICE
INT32 mp3version_check(UINT8 para);
#endif

extern struct img_callback g_mus_cb;
int music_engine_init(struct pe_music_cfg *pe_music_cfg)
{
#ifdef _INVW_JUICE
    mp3version_check(0);	
#endif
    g_mus_cb.mp_cb = pe_music_cfg->mp_cb;
    jump_to_func(NULL, OS_hld_caller, pe_music_cfg, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(1<<16)|FUNC_MUSIC_ENGINE_INIT, desc_me_init);
}

void music_engine_release()
{
    jump_to_func(NULL, OS_hld_caller, null, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(0<<16)|FUNC_MUSIC_ENGINE_RELEASE, NULL);
}

static int music_engine_play_naked(char *filename)
{
    jump_to_func(NULL, OS_hld_caller, filename, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(1<<16)|FUNC_MUSIC_ENGINE_PLAY, NULL);
}

int music_engine_play(char *filename)
{
    filename = mp_flush_file_name(filename);
    return music_engine_play_naked(filename);
}

void music_engine_seek(int time)
{
    jump_to_func(NULL, OS_hld_caller, time, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(1<<16)|FUNC_MUSIC_ENGINE_SEEK, NULL);
}

void music_engine_stop(void)
{
    jump_to_func(NULL, OS_hld_caller, null, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(0<<16)|FUNC_MUSIC_ENGINE_STOP, NULL);
}

void music_engine_pause(void)
{
    jump_to_func(NULL, OS_hld_caller, null, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(0<<16)|FUNC_MUSIC_ENGINE_PAUSE, NULL);
}

int music_engine_get_time(void)
{
    jump_to_func(NULL, OS_hld_caller, null, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(0<<16)|FUNC_MUSIC_ENGINE_GET_TIME, NULL);
}

void music_engine_set_eq(int on, float preamp, float *bands)
{
    jump_to_func(NULL, OS_hld_caller, on, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(3<<16)|FUNC_MUSIC_ENGINE_SET_EQ, desc_me_set_eq);
}

static int music_engine_get_song_info_naked(char * filename, MusicInfo *music_info)
{
    jump_to_func(NULL, OS_hld_caller, filename, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(2<<16)|FUNC_MUSIC_ENGINE_GET_SONG_INFO, desc_me_get_song_info);
}

int music_engine_get_song_info(char * filename, MusicInfo *music_info)
{
    filename = mp_flush_file_name(filename);
    return music_engine_get_song_info_naked(filename, music_info);
}

static int music_engine_get_decoder_info_naked(char * filename, DecoderInfo *decoder_info)
{
    jump_to_func(NULL, OS_hld_caller, filename, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(2<<16)|FUNC_MUSIC_ENGINE_GET_DECODER_INFO, desc_me_get_decoder_info);
}

int music_engine_get_decoder_info(char * filename, DecoderInfo *decoder_info)
{
    filename = mp_flush_file_name(filename);
    return music_engine_get_decoder_info_naked(filename, decoder_info);
}

void music_engine_set_disableSeek(UINT8 disable)
{
    jump_to_func(NULL, OS_hld_caller, disable, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(1<<16)|FUNC_MUSIC_ENGINE_SET_DISABLE_SEEK, NULL);
}

int music_engine_set_other_info(UINT32 cmd, UINT32 param1)
{
    MusicInfo *ppara = NULL;
    UINT32 *desc = NULL;
    switch(cmd)
    {
        case MP_SET_NETWORK_OTHER_INFO:
            ppara = (MusicInfo *)param1;
            desc = desc_me_set_other_info;
            break;
        default:
            break;
    }
    jump_to_func(NULL, OS_hld_caller, cmd, (LIB_PE_MUSIC_ENGINE_MODULE<<24)|(2<<16)|FUNC_MUSIC_ENGINE_SET_OTHER_INFO, desc);
}

#endif

#endif

